﻿using Common;
using IRepository;
using Microsoft.EntityFrameworkCore;
using Model;
using ModelDto;
using Newtonsoft.Json;
using SqlserverManager;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Repository
{
    public class BaseRepository<T> : IBaseRepository<T> where T : BaseDBModel, new()
    {
        protected SqlSugarClient Context { get; private set; }
        protected IDbConnectionFactory _IDbConnectionFactory { get; private set; }

        private readonly IRedisHelper _redisHelper;

        /// <summary>
        /// 缓存列表key
        /// </summary>
        private readonly string CacheListAllKey = $"{typeof(T).Name}-ALL";

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="DbConnectionFactory"></param>
        /// <param name="redisHelper"></param>
        public BaseRepository(IDbConnectionFactory DbConnectionFactory, IRedisHelper redisHelper)
        {
            this._IDbConnectionFactory = DbConnectionFactory;
            this._redisHelper = redisHelper;
        }

        #region 同步

        /// <summary>
        /// 查找 - 通过ID
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T Find(string id)
        {
            Context = _IDbConnectionFactory.CreateDbContext();


            return  Context.Queryable<T>().Where(a => a.IsDelete == false && a.Id == id).First();
        }
        /// <summary>
        /// 查询实体对象 通过条件
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public T Query(Expression<Func<T, bool>> whereLambda)
        {
            Context = _IDbConnectionFactory.CreateDbContext();
            return  Context.Queryable<T>().Where(whereLambda).Where(a => a.IsDelete == false).First();

        }

        /// <summary>
        /// 查询列表 通过条件
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public List<T> QueryList(Expression<Func<T, bool>> whereLambda)
        {
            Context = _IDbConnectionFactory.CreateDbContext();
            return  Context.Queryable<T>().Where(a => a.IsDelete == false).Where(whereLambda).ToList();
        }


        /// <summary>
        /// 查询列表 通过条件 包括删除数据 
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public List<T> QueryListIncludeDelete(Expression<Func<T, bool>> whereLambda)
        {
            Context = _IDbConnectionFactory.CreateDbContext();

            return  Context.Queryable<T>().Where(whereLambda).ToList();
        }
        /// <summary>
        /// 查询列表分页 - 通过条件
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public (List<T>,int) QueryList(Expression<Func<T, bool>> whereLambda, int pageIndex, int pageSize, Expression<Func<T, object>> orderbyWhere, OrderByType orderByType)
        {
            Context = _IDbConnectionFactory.CreateDbContext();

            int count = 0;

            var list = Context.Queryable<T>()
                   .Where(whereLambda)
                   .Where(a => a.IsDelete == false)
                   .OrderBy(orderbyWhere, orderByType)
                   .ToPageList(pageIndex, pageSize, ref count);

          return new (list,count);
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public T AddBackEntity(T entity)
        {
            Context = _IDbConnectionFactory.CreateDbContext();
            var result =  Context.Insertable<T>(entity).ExecuteCommand();
             
            if (result > 0)
            {
                ClearCache();
                return entity;
            }

            return null;
        }
        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public bool Add(T entity)
        {
            Context = _IDbConnectionFactory.CreateDbContext();


            var result =  Context.Insertable<T>(entity).ExecuteCommand();

            if (result > 0)
            {
                ClearCache();
            }

            return result > 0;
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public bool Update(T entity)
        {
            Context = _IDbConnectionFactory.CreateDbContext();
          
            var result =  Context.Updateable<T>(entity).ExecuteCommand();

            if (result > 0)
            {
                ClearCache();
            }
            return result > 0;
        }
        /// <summary>
        /// 实体删除
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public bool Dellete(T entity)
        {
            Context = _IDbConnectionFactory.CreateDbContext();

            var result =  Context.Deleteable<T>(entity).ExecuteCommand();

            if (result > 0)
            {
                ClearCache();
            }
            return result > 0;
        }

        /// <summary>
        /// 条件删除
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public bool DeleteByWhere(Expression<Func<T, bool>> whereLambda)
        {
            Context = _IDbConnectionFactory.CreateDbContext();

            List<T> list = Context.Queryable<T>().Where(whereLambda).ToList();

            var result =  Context.Deleteable<T>(list).ExecuteCommand();
           
            if (result > 0)
            {
                ClearCache();
            }
            return result > 0;
        }

        /// <summary>
        /// 获取列表 - 缓存 所有
        /// </summary>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public List<T> GetListCache()
        {

            string cacheList = _redisHelper.GetValue(CacheListAllKey);
            if (!string.IsNullOrWhiteSpace(cacheList))
            {
                var resCache = JsonConvert.DeserializeObject<List<T>>(cacheList);

                return resCache;
            }


            //数据读
            Context = _IDbConnectionFactory.CreateDbContext();

            var dbList = Context.Queryable<T>().Where(a => a.IsDelete == false).ToList();

            if (dbList != null && dbList.Count > 0)
            {
                //没数据 不缓存
                _redisHelper.SetValue(CacheListAllKey, JsonConvert.SerializeObject(dbList));
            }

            return dbList;
        }

        #endregion

        #region 异步

    
        /// <summary>
        /// 查找 - 通过ID
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<T> FindAsync(string id)
        {
            Context = _IDbConnectionFactory.CreateDbContext();


            return await Context.Queryable<T>().Where(a => a.IsDelete == false && a.Id == id).FirstAsync();
        }
        /// <summary>
        /// 查询实体对象 通过条件
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public async Task<T> QueryAsync(Expression<Func<T, bool>> whereLambda)
        {
            Context = _IDbConnectionFactory.CreateDbContext();
            return await Context.Queryable<T>().Where(whereLambda).Where(a => a.IsDelete == false).FirstAsync();

        }

        /// <summary>
        /// 查询列表 通过条件
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public async Task<List<T>> QueryListAsync(Expression<Func<T, bool>> whereLambda)
        {
            Context = _IDbConnectionFactory.CreateDbContext();
            return await Context.Queryable<T>().Where(a => a.IsDelete == false).Where(whereLambda).ToListAsync();
        }


        /// <summary>
        /// 查询列表 通过条件 包括删除数据 
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public async Task<List<T>> QueryListIncludeDeleteAsync(Expression<Func<T, bool>> whereLambda)
        {
            Context = _IDbConnectionFactory.CreateDbContext();

            return await Context.Queryable<T>().Where(whereLambda).ToListAsync();
        }
        /// <summary>
        /// 查询列表分页 - 通过条件
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public async Task<(List<T>, int)> QueryListAsync(Expression<Func<T, bool>> whereLambda, int pageIndex, int pageSize, Expression<Func<T, object>> orderbyWhere, OrderByType orderByType)
        {
            Context = _IDbConnectionFactory.CreateDbContext();

            RefAsync<int> count = 0;

            var list = await Context.Queryable<T>()
                   .Where(whereLambda)
                   .Where(a => a.IsDelete == false)
                   .OrderBy(orderbyWhere, orderByType)
                   .ToPageListAsync(pageIndex, pageSize, count);

            return new(list, count);

        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public async Task<T> AddBackEntityAsync(T entity)
        {
            Context = _IDbConnectionFactory.CreateDbContext();
            var result = await Context.Insertable<T>(entity).ExecuteCommandAsync();

            if (result > 0)
            {
                ClearCache();
                return entity;
            }

            return null;
        }
        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public async Task<bool> AddAsync(T entity)
        {
            Context = _IDbConnectionFactory.CreateDbContext();


            var result = await Context.Insertable<T>(entity).ExecuteCommandAsync();

            if (result > 0)
            {
                ClearCache();
            }

            return result > 0;
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public async Task<bool> UpdateAsync(T entity)
        {
            Context = _IDbConnectionFactory.CreateDbContext();

            var result = await Context.Updateable<T>(entity).ExecuteCommandAsync();

            if (result > 0)
            {
                ClearCache();
            }
            return result > 0;
        }
        /// <summary>
        /// 实体删除
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public async Task<bool> DelleteAsync(T entity)
        {
            Context = _IDbConnectionFactory.CreateDbContext();

            var result = await Context.Deleteable<T>(entity).ExecuteCommandAsync();

            if (result > 0)
            {
                ClearCache();
            }
            return result > 0;
        }

        /// <summary>
        /// 条件删除
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public async Task<bool> DeleteByWhereAsync(Expression<Func<T, bool>> whereLambda)
        {
            Context = _IDbConnectionFactory.CreateDbContext();

            List<T> list = Context.Queryable<T>().Where(whereLambda).ToList();

            var result = await Context.Deleteable<T>(list).ExecuteCommandAsync();

            if (result > 0)
            {
                ClearCache();
            }
            return result > 0;
        }

        /// <summary>
        /// 获取列表 - 缓存 所有
        /// </summary>
        /// <param name="writeOrRead"></param>
        /// <returns></returns>
        public async Task<List<T>> GetListCacheAsync()
        {

            string cacheList = _redisHelper.GetValue(CacheListAllKey);
            if (!string.IsNullOrWhiteSpace(cacheList))
            {
                var resCache = JsonConvert.DeserializeObject<List<T>>(cacheList);

                return resCache;
            }


            //数据读
            Context = _IDbConnectionFactory.CreateDbContext();

            var dbList = await Context.Queryable<T>().Where(a => a.IsDelete == false).ToListAsync();

            if (dbList != null && dbList.Count > 0)
            {
                //没数据 不缓存
                _redisHelper.SetValue(CacheListAllKey, JsonConvert.SerializeObject(dbList));
            }

            return dbList;
        }

        #endregion

        #region 缓存

        /// <summary>
        /// 清除缓存
        /// </summary>
        protected void ClearCache()
        {
            _redisHelper.DeleteKey(CacheListAllKey);
        }


        #endregion
    }
}
